27
\$\begingroup\$

I'm working on a game with a component-based architecture. An Entity owns a set of Component instances, each of which has a set of Slot instances with which to store, send, and receive values. Factory functions such as Player produce entities with the required components and slot connections.

I'm trying to determine the best level of granularity for components. For example, right now Position, Velocity, and Acceleration are all separate components, connected in series. Velocity and Acceleration could easily be rewritten into a uniform Delta component, or Position, Velocity, and Acceleration could be combined alongside such components as Friction and Gravity into a monolithic Physics component.

Should a component have the smallest responsibility possible (at the cost of lots of interconnectivity) or should related components be combined into monolithic ones (at the cost of flexibility)? I'm leaning toward the former, but I could use a second opinion.

\$\endgroup\$
3
  • \$\begingroup\$ Similar question: gamedev.stackexchange.com/questions/4914/… \$\endgroup\$
    – Den
    Jul 9, 2011 at 12:02
  • \$\begingroup\$ Are you going to use your own physics engine or integrate an existing one? \$\endgroup\$
    – Den
    Jul 9, 2011 at 12:07
  • \$\begingroup\$ @Den: I'm writing some physics code, but it's not an engine by any means. Just mundane 2D kinematics. \$\endgroup\$
    – Jon Purdy
    Jul 9, 2011 at 22:54

4 Answers 4

14
\$\begingroup\$

There's a line between complete granularity, leading to no code wastage or blob-like state (which is why component architectures are favoured), and usability.

Obviously things may have a Position, but they're not necessarily dynamic (so why have Velocity and Acceleration?). However, something with a Velocity is going to be a moving object, so it makes sense to also have Acceleration grouped.

Are you going to have a case where v and a are going to be needed, but you don't want a physics simulation for them? Similarly, is there going to be a point in Gravity if they're not physics objects?

tl;dr Group what makes sense.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Sounds fair. My system has very little centralisation: if an Entity has a Position and some components that make that Position participate in physics, then the Entity is de facto physical. I think what I may do is just add some components for logical grouping, and keep all the fundamental components to a single responsibility. So adding, say, a Movable to an Entity would have the same effect as adding a Position, Velocity, and Acceleration. \$\endgroup\$
    – Jon Purdy
    Jul 8, 2011 at 15:41
6
\$\begingroup\$

To avoid micromanaging each and every variable I'd suggest by starting heavy, choose divisions around responsibility and refactor when the situation presents itself logically. You can start the first designs on paper. At some point these gross divisions of responsibility will become the building blocks of your entities.

So for a rushed example you have Game. Game splits into Environment + State. Environment splits into StaticWorld + MovingStuff. State splits into AIControlled + PlayerControlled. The gross idea of Damage splits into TakesDamage + GivesDamage.

And so on.

Much like the common advice to "Build games, not engines!" for new practitioners I recommend "Build Games, not elaborate component systems!" because only with personal experience with a running game will you know whether an elaborate component system is called for in future works.

\$\endgroup\$
3
  • \$\begingroup\$ I'm not a new developer. If I have components based on concepts rather than behaviour (i.e., top-down versus bottom-up), won't my architecture be more brittle, and more elaborate? I can implement any behaviour I want from small components, but I can't always get the desired behaviour from precombined ones. Not to mention that I can't predict everything I'll want to achieve even in the context of one game. \$\endgroup\$
    – Jon Purdy
    Jul 8, 2011 at 19:21
  • \$\begingroup\$ The drawback to bottom-up is that communications between components becomes a problem, and people tend to start way too micro on the scale of what they're modeling. I was mainly trying to steer away from the super-micro "xyz is a component" "rotation is a component" "rgb is a component" level for someone inexperienced. \$\endgroup\$ Jul 8, 2011 at 19:50
  • \$\begingroup\$ Fair enough. I just wanted to make sure I understood you correctly. With the slot system I have, it's simple and efficient for components to communicate, so I really don't see any drawbacks to the "super-micro" scale. I don't intend to refactor this into a standalone engine, but if I do, then I can always introduce abstractions such as the component groups I mention in my comment on The Communist Duck's answer. \$\endgroup\$
    – Jon Purdy
    Jul 8, 2011 at 20:02
4
\$\begingroup\$

My guess would be to combine components who will have lots of interaction. In your case, i'd keep the position in a single component, and have the velocity & acceleration kept together in a physics component.

But it depends a lot on what your game features are (unless you're building a framework with no specific game in mind).

\$\endgroup\$
1
  • 2
    \$\begingroup\$ The problem with combining components with a lot of interaction is that sometimes the other part isn't needed. \$\endgroup\$ Jul 9, 2011 at 11:44
4
\$\begingroup\$

I realize this is an old question but maybe someone will find this answer useful.

I believe that Systems will better help you to understand how to construct Components. Systems exist in architectures where components don't contain their own logic, aside from simple getter/setters and helper functions. Systems operate on Entities which satisfy the Component requirements. This is why it is best to separate component data as much as it makes sense for that data to be processed without the other data.

For example, you might have a MovementSystem which updates its Entities' Position based on their Velocity. This could be for simple entities in the game. But, for the Player and Enemies, you might want movement that has Acceleration which is processed in AcceleratedMovementSystem. But for Obstacles you might want Friction. The Terrain might also have friction, but it won't have a velocity component. But what about Gravity? Just add it Player, Enemy, and Obstacle, and create a GravitySystem to process it.

The bottom line is that the more decoupled your Components are, the more extensible the Entities will be when using Systems.

Edit: Made last statement clearer.

Edit: Ok, I've been working on my own System and came to this realization. An example for splitting up Position and Velocity is that manipulating Velocity causes the Position to change with a MovementSystem. As a result, an 'InputMovementSystem' doesn't need a Position to cause the Player to move from user Input because the MovementSystem will pick up the changes in Velocity to apply to Position. Granted, it would still work fine to put them together, but thats an example of why the don't need to be.


I read a blog post recently that said something like this:

"If you have data that can be grouped with 2 different components, it is best to create a third component with that data."

\$\endgroup\$

You must log in to answer this question.

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