Is my approach of an Area2D manager correct?

Godot Version

4.6

Question

Hello. I’m trying to solve an architectural problem but I’m not sure if my solution is better or worse than what I was doing before.

I have several components that need an Area2D to work. So what I was doing is that the component itself is an Area2D. For example, a HittableComponent, a FlammableComponent or a InteractableComponent.

The thing is that the HittableComponent and the FlammableComponent areas might be exactly the same. And the InteractableComponent might be slightly bigger. This leaves me with 3 different areas, when two of them could be exactly the same. In areal case scenario this can be up to 10 different areas that are identical.

So I’ve come up with the idea of an area manager:

  • This node can have one or more Area2D inside.
  • Each component exposes a variable that lets me choose which area they want to be registered to.
  • Upon initialization, the area manager registers which nodes are available to each area in a dictionary.
  • Areas expose a method called get_component that allows to ask the area manager for a certain type of node, and return it.
  • When something detects an area, it calls the get_component from that area.

This way, I can have only one Area2D that covers all the components for most of the cases. The only downside is that everytime I call the get_component method, I have to iterate the whole list of components and perform a is_instance_of on each one.

I think that’s still cheaper than having several Area2D that are identical, but I’m not sure.

What are your takes on this?

I believe the main cost of area2ds is the active scanning area size. You will still end up with the same total size.

If i would want to minimize the performance cost i would try to turn scanning on an off as needed. For example if you have lots of interactive areas attached to items etc, keep them off and instead let the area that will detect be on. Then you have one area attached to the player scanning for the 30 item areas, instead of the 30 item areas scanning for the one player area.

So if I have 1, 10 or 100 Area2D that occupy the same exact spot, the cost is the same? Do you have any source where I can read about this?

No because the area for each node will combine into a much bigger area, even if they all scan the same.what i meant is that the active scanning and the area scanned is what contributes most the performance cost. So if you can avoid having actively scanning areas you will avoid a lot of the cost. Set the ones that dont need to be active to inactive and let a small area on your player scan for them, that will save you a lot of the performance without any need for complexity.

Did you measure any significant performance bottlenecks?

I don’t think you need to make a manager.
Make your components inherit from Node and export an Area3D variable. Connect the relevant signals on _Ready().
Then you can plug the same area3d to multiple components instead o each being its own area3d.

You can even connect the signals in editor instead of exporting a reference to the Area3D if you prefer.

@amarc lol, you’re right. I just added an extra step with the manager when the area itself can return its own registered nodes.

But the rest of the idea seems to be in line with what you’re commenting. So I’m not crazy about the idea of sharing a single area for multiple nodes.

Replying to @normalized, I didn’t really experience a bottleneck (although I’m worried about it, not sure if I should be), but it’s a lot of overhead to have multiple Area2D that are exactly the same. I don’t like having the editor cramped with little colored squares all over the place.

You shouldn’t. Don’t presume there’s an overhead, always measure using the profiler. And watch out for the premature optimization trap.

And yeah, if you find yourself having a “manager” in your system, you’re likely doing something wrong (or at least over-complicated) in terms of organization/architecture.