2
\$\begingroup\$

To clarify, by overlapping I do not mean overlapping between said components, but rather, let's say I have:

  • My entity contains components, and a parent-children system. Call it a mandatory Hierarchy component if you may.
  • A Transform component that has x, y, r, sx, sy, and relative properties.
  • A Drawable component family that is drawn by a RenderingSystem, it uses position information from Transform.
  • Script components that can read and manipulate position of objects.

Now, what I want to add is a Box2DPhysics component family(shape(s), body) and a Box2DPhysicsSystem that internally just updates the physics world, but the problem is: The Transform component is not compatible with that. Box2D has its own internal position, rotation, velocity information, that here can only be accessed via getter and setter methods. Now, it's not impossible for me to wrap the Transform component's fields and methods to use said getters/setters, but then I'm implementing half of the functionality in the Transform component...

Now, what should I do? Some options that come to my mind would be:

  1. Make the physics component override the Transform component, somehow. Either by writing its position info into Transform every frame, or something like that

  2. Allow some components to be two or more subcomponent, such as Box2DPhysics being both a Physics component and a Transform component.

  3. Not use Box2D whatsoever, write my own verlet-based physics engine, likely significantly slower, but functional and fully interoperational with the rest of the code.

  4. "Freeze" some of the components and functionality, effectively making it 100% built-in - prohibit the user from replacing or implementing few basic most important components, and handle things like this interally.

I feel like personally I'm leaning towards #2, but honestly, I just don't know. It's probably my anxiety/indecisiveness that is at fault, but I feel like I simply cannot proceed without getting someone's opinion.

\$\endgroup\$
1
\$\begingroup\$

While you may find it useful to cache your entity's position in your PhysicsComponent, it's primary purpose should be to supply physical characteristics about the entity such as mass, volume, rigid properties, etc.

Your PhysicsSystem would be responsible for obtaining the current position from your Transform, the velocity/accelleration from your Velocity component and using those in conjunction with the physics library to force the entity to move appropriately. After the simulation, the system in turn updates the Transform position and orientation appropriately as well as notifies objects of collisions.

The benefit here is that if you replace your physics library, the remainder of your code should continue to work and only the PhysicsSystem needs to be adjusted to work with the new library. This doesn't conform to any of your points exactly, but does lend itself to being very compartmentalized and decoupled to permit ease in refactoring as needed.

\$\endgroup\$
  • \$\begingroup\$ Ah... that sounds like exactly the subtle variant of what I thought about. I thought about Transform as being mandatory for everything, while the rest could all be put into one, but you are right, that's somewhat missing the point of the C-E architecture. The biggest downside is probably the fact that it'll be somewhat slow-ish, even with LuaJIT's speed. I sort of feel like C-E is more suited for lower level languages, because it needs to take ownership of the data. I'll accept your answer later, if no one says anything useful, since I wouldn't mind hearing another perspective. \$\endgroup\$ – Llamageddon Oct 25 '14 at 21:17
  • \$\begingroup\$ That's somewhat subjective depending on your approach to how you store component data. I've seen implements in LUA and other scripting languages and they work just fine. It isn't uncommon to prototype components in a scripting language, get their functionality working as desired and then port them to the native language if performance becomes a problem. \$\endgroup\$ – Naros Oct 27 '14 at 14:42
  • \$\begingroup\$ Well, I'm writing this in general atop of Lua and Love2D, without anything underlying as of now. But yeah, that's fairly simple and I might do just that - but not now. This issue and others made me realize that I obsess with perfection far too much. I have a problem with coding and I need to take a step back, and once I come back I'm writing simple prototypes, not engines, class systems, language drafts and other unnecessary things. Thanks for your answer, I think I'll accept it over the other two :) \$\endgroup\$ – Llamageddon Oct 27 '14 at 17:48
0
\$\begingroup\$

Here is another thought, Although I'm not sure how good it will perform:

The thing is, the Transform component is mandatory, but it doesn't really matter the internal class is, as long as it provides position, rotation and other details about an object's spacial properties.

What I mean is, you can have to classes, both providing all the information necessary. But a class doesn't need to have both of those components. In fact those two (physics and transform) can not be present at a same time, but only one them should be attached to each entity. To make it even easier they might even share a base parent component class.

\$\endgroup\$
  • \$\begingroup\$ Hmm, I don't think I like this solution, I think a component providing multiple subcomponents would be a similar but better idea. Well, mostly identical to this. Well, thank you for your perspective, but I think I'll either do that, or go with what crancran suggests, so I'll accept his answer. \$\endgroup\$ – Llamageddon Oct 26 '14 at 21:24
  • \$\begingroup\$ I think this approach adds a level of inheritance and coupling that can be avoided by using separate components for their specific tasks. It isn't uncommon to have objects require some spatial information but aren't controlled by physics while some may require both. Keeping them separate keeps the code clean IMO and when you need spatial information, you get it from the transform/spatial component regardless whether the entity is physics controlled or not. What would you do if you temporarily disabled physics allowing a player to fly? \$\endgroup\$ – Naros Oct 27 '14 at 14:38
0
\$\begingroup\$

In my implementation I have a ITransform interface. The transform is implemented either with a standalone Transform (implementing the ITransform) or when using 2D physics with the Box2DComponent (which also implements the ITransform).

This way I can chose to directly use physics or not depending on each entity's purpose and both types can coexist in the same game even if their transform components don't register in the same systems.

An entity can only have one ITransform so this setup works well and I can even switch basic entities to use Box2D with minimal changes in the game logics.

\$\endgroup\$
  • \$\begingroup\$ Is it an engine or just a way to manage your functionality? What are you coding in and what libs/frameworks are you using? \$\endgroup\$ – Llamageddon Oct 26 '14 at 18:51
  • \$\begingroup\$ @Asmageddon It's a small engine I wrote and used in conjunction with cocos2dx 2.x. \$\endgroup\$ – Coyote Oct 27 '14 at 12:14

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.