C# Design Patterns – How to Make Components Communicate with Each Other

Architectureccompositiondesign-patterns

I have a simple setup where I've decided to reduce my overall OOP design and opt for lots of small individual components that I can add and remove from a particular object.

The whole point of this was so components could be added and removed with out depending on other components – essentially they are decoupled.

But this is hard to setup in my case, as I have an object that depending on some of its components attached will depend on whether it is functional.

Let me give an example:

Say the object is a SecurityCamera object for a stealth game.

It has the following components attatched:

Vision // defines what it can see
PowerInput // defines if it currently recieves power
Health // defines if it is damaged
Movement // Whether the camera can move back and forth depends on health and power being available

Now since each component is separate the problem I have is that the Movement script needs to know about Health and PowerInput. It cannot move the camera unless the camera has health and power.

Currently the way I have done it is a bit lazy: The Movement component checks the state of the Health and PowerInput components in every frame. To me that's not ideal, I'd prefer a less expensive check that I don't have to do in every frame, in that if Health reaches 0 or PowerInput no longer gets power, movement will then stop working.

What is the clean/performant way to link Movement to PowerInput and Health and for movement to be aware of the state of those components so it decides if it can move or not?

It's very easy at the moment for it to break if I forget one of the components so its going to get messy as i develop a project with lots of components for a variety of objects where they depend on each other a lot.

I use C# for my project though this isn't particular language specific.

Best Answer

To me thats not ideal, I'd rather a less expensive check that i don't have to do every frame, in that if Health reaches 0 or PowerInput no longer gets power, movement will then stop working.

Be very, very careful here. It's not that you can't change your logic to be event-driven, but event-driven systems can get really complex and difficult to debug. In any sizeable codebase, you quickly lose the overview because events obfuscate the flow of your logic at runtime.

For example, while both PowerInput and Health are individually able to disable Movement, neither of them is individually able to enable it. Just because the power is restored doesn't mean that the health still isn't 0. This inherently requires some logic that spans across the three components in order to make that combined evaluation, which goes against the very outset you're starting from here (I agree with the posted comment that decoupling doesn't mean zero dependency and that you may be setting the bar too high).

It might not matter when your game only deals with the act of disabling cameras and never being able to re-enable them, but it is a very important consideration when you start applying this pattern at large.

Checking the value of an in-memory variable is not a significant performance hit in any way. There is likely no actual performance bottleneck to address here, no matter how many security camera objects are running in your level. Unless there is some underlying IO operation here, which I very much doubt, I would suggest you don't try to prematurely optimize this at all.

Related Topic