1
\$\begingroup\$

I am working on an entity-component system, and I am thinking about this communication protocol:

  1. The physics component of a game object sends an UpdateMyState message, with its state attached.
  2. The physics engine receives this.
  3. The physics component sends a pointer to its data, and the physics engine changes the state. Because it is a pointer, no messaging back is required.

The standard way involves the physics engine sending back an UpdatedState message, with the new state attached. This will be processed by the physics component. I am not sure if my way is a good exercise. It is not a complete message-based system, but it decreases the amount of required messages, and it simplifies the system.

What are the advantages and disadvantages of using pointers to change data in my physics engine?

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

IMHO Yes, your implementation is a good one.

This allows your physics engine to run on it's own, and be decoupled of your ECS structure.

  1. Physics component registers its physics object to the physics engine when it's created
  2. Graphics component registers its graphics object to the graphics engine when it's created
  3. Main infinite loop has the input processed
  4. Main infinite loop calls for physics engine update
  5. Physics engine does it's simulation: collision detection and resolution
  6. Main infinite loop sends the message to update the transform
  7. Main infinite loop sends the message to update the game logic
  8. Main infinite loop calls for the graphics engine update

This will de-couple your graphics and physics engines from your ECS and reduce the load of messages sent through that channel.

Of course, this is on paper. You'll have to implement it and try it for yourself. Try a design that seems to work for you first, then finish your project and improve it for your second project.

\$\endgroup\$
  • \$\begingroup\$ So I shouldn't focus on creating a fully modular engine, rather focus making an easily maintainable, understandable, reasonable system. (So giving up some of the modularity to make it better in other, more important aspects of design) Oh, I think I misunderstood it. You mean that the component has a physics object (like position, velocity, physical material, etc), and the physics engine has a pointer to that object too, so the engine can directly manipulate it? That decreases modularity, doesn't it? \$\endgroup\$ – Tudvari Dec 8 '16 at 12:24
  • 1
    \$\begingroup\$ @Tudvari "You mean that the component has a physics object (like position, velocity, physical material, etc), and the physics engine has a pointer to that object too, so the engine can directly manipulate it?" Yes. And it decreases modularity a bit, but you gain in de-cluttering the amount of messages sent out. Keep in mind that the danger with a hammer is to see everything as being a nail. Just like for an ECS, one has to see what fits well as a full component and what does not fit as well. \$\endgroup\$ – Alexandre Vaillancourt Dec 8 '16 at 12:51
  • 1
    \$\begingroup\$ @Tudvari Ultimately, the answer is "try both paths, and see what works best for your situation" :P You'll learn a lot in the process :) \$\endgroup\$ – Alexandre Vaillancourt Dec 8 '16 at 12:53
  • \$\begingroup\$ 1 extra question: Both graphics object and physics object relies on the objects transform. So I can't store it in one of the objects, because they need it the same way, and I can't store it in both, because it's redudant. Doesn't that suggests that I should make a Transform component? But then somehow the 2 object should reach this transform. Messaging is not viable, because messaging for each frame is not so efficient.Storing pointers in the objects to the transform would deeply break modularity. \$\endgroup\$ – Tudvari Dec 8 '16 at 13:32
  • 1
    \$\begingroup\$ @Tudvari This depends on the communication channel between your components. Typically, the physics will modify the transform, and the other components will use it. If your components can 'talk' to each other, you could store a pointer to the transform (which is in the Transform component) in the other components, or something like that. If you only use messages, then I would suggest that the transform value is sent along, and that the other components that use it store a copy of it (it's redundant yes, but you'd otherwise have to have much more messages, from what I understand of your design). \$\endgroup\$ – Alexandre Vaillancourt Dec 8 '16 at 13:52
2
\$\begingroup\$

Your method will reduce encapsulation, meaning that the different systems will be more closely linked, and therefore changes to one of the them might mean large changes to the other. Other advantages of encapsulatio are outlined in the wikipedia aritcle.

Another thing your method will detract from is polymorphism, I'd assume that different types of physics components would need to be processed slightly differently. Therefore you could have an abstract class which each component inherits form, then the engine calls the same abstract method in each component and is therefore much simpler, all the difficult stuff is done by the components rather than having some horrible switch block in the engine. This would mkae it much easier to add different types of physics components.

\$\endgroup\$
  • \$\begingroup\$ So then the engine only gives back to the objects for example what thing they have collided with? And then the different type of physics components handle the collosion differently? \$\endgroup\$ – Tudvari Dec 8 '16 at 10:57
  • \$\begingroup\$ Is this good example: -in the main infinite loop there is a message sent to update the physics. -The physics component calculates its collider's next position. -Sends message to Physics engine to check collision. -Physics Engine sends back collision data (if there is) -Physics component changes its status based on the physics engine's answer. -main infinite loop calls transform updates. -Transform components send message to Physics component -Physics component sends back location change. -Transform updates it location. -(And then the render engine sends msg-s to transform, etc) \$\endgroup\$ – Tudvari Dec 8 '16 at 11:02
  • 1
    \$\begingroup\$ that sounds good to me, but why are you separating physics and transform components? \$\endgroup\$ – benh Dec 8 '16 at 11:16
  • \$\begingroup\$ Because not all the objects can have a physical form, but every objects has a position. Like a ball of light. Or should I just combine them, and this component will have a PhysicMaterial member variable, which will determine its collision behaviour, and If I don't want to care about collision I just leave it to null? Oh, and so the physics engine is just a container for colliders, which checks collision between colliders? Isn't that too little role for it? \$\endgroup\$ – Tudvari Dec 8 '16 at 11:27
  • 1
    \$\begingroup\$ Yeah that seems like a good idea. You probably want to store all your physics constants in your physics engine, but it being simple is far from a bad thing \$\endgroup\$ – benh Dec 8 '16 at 11:42

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.