Turning off collision messages

I’ll kick off my presence in this forum with a request of more general nature that might benefit from thoughts from other people:

In our game we have a lot of enemies with different behaviours. These are, as of now at least, handled by separate scripts. What we see when we have a lot of enemies moving in group is that they collide with each other creating a flood of collision_response and contact_point_response messages to all scripts on each enemy in every frame.
What I would like to propose is a way to tell Defold that a certain script is not interested in messages regarding physics - kind of like acquire_input_focus works today - but with the difference that all scripts automatically get the messages unless explicitly told otherwise. So I would send something like msg.post(".", “release_physics_focus”) from a script and that script would not receive physics messages. In that way we would reduce a lot of redundant on_message calls, since only a few of the behaviours are actually physics dependent. This would also allow for all physics to go through one script that acts as a proxy.

Welcome to the forum!

Isn’t your particular problem solvable with collision groups?

I am not sure in what way? The enemies are supposed to collide with each other, so the problem is not the collision_responses per se, but the fact that it is sent to all scripts on each enemy gameobject.

Or am I missing something?

Hmmm, I don’t see how what you propose would result in fewer messages. They would only be directed differently, right? Or are your enemies perhaps dynamic objects and you’re only interested in having the physics engine separate them and not receive messages for those collisions?

(Note: messages in large quantities are currently expensive, especially on devices so it can definitely be a good idea to try to reduce their numbers)

As I said our enemies can have different behaviours, each defined in a script that is added to a game object. A hypothetical enemy that is a chameleon snake could then have these behaviours:

  • Moves
  • Slithers
  • Attacks
  • Melee
  • Poisonous
  • Killable
  • Camouflage

Of these only a few would actually need collision messages, and those that do could easily receive fewer messages with an additional script that gets all collision and proxies them to the relevant script. As it is now if we have a sphere co on each enemy and they move in a group they would each receive one collision_response and two contact_point_response for each other enemy they collide with, and those three messages would be sent to seven scripts.

Aha! Sorry, I misunderstood first, but get it now.

Currently, the best way to solve the problem is probably to limit the number of script components in each game object (since the physics messages are broadcast to everyone) and instead write the behaviors in separate Lua modules that you include.

I will bring this up with the team. There are already some ideas floating around on how to deal with floods of physics messages, but there is no specific design or plan in the backlog yet.

Yes, that is the route we are currently going to go. The big downside of that approach is that it is not as flexible, easily maintained and simple to use as having the behaviours in scripts. So far it also creates a lot of trying-to-fit-the-square-block-in-a-round-hole type situations.

I agree with Johan here. I’m doing a platformer as a side-project and the enemies have many small scripts attached that build their behaviour. It’s a lot more convenient to attach script to build behaviour than it is to require() a bunch of modules and hook them up to the game object life-cycle functions. And it’s a lot less obvious when you inspect a game object which behaviour it has if you hide it in many required modules. Another disadvantage of using modules is that you’re not able to have go.property() calls in modules to declare and expose module/script specific values as you would have been able to if you had your logic in scripts.

Yes, I agree. It’s more natural to set the logic up with several script components. However, if the goal is to limit the number of collision messages, there are currently few options.

I realized that one way of achieving what I think Johan wants is a setup with two separate game objects:

  1. A collision GO with one script component that receives collision messages and dispatch messages to…
  2. A behavior GO with any number of script components, one for each behavior.

Build the enemy with its game objects in a collection and spawn them with the new collection factory component.

Btw, have you done any profiling of the performance impact of these collision messages?

Yes, a setup with two GOs and some kind of “here I am and I’m interested in collision messages” registration from those scripts that care about collisions could be one way of solving the problem.

No, I haven’t done any profiling, but if you have 6-10 scripts that each have an on_message and a bunch of conditional checks in each on_message, then I’m fairly sure it has a measurable impact when profiling. On the other hand as long as you’re below your frame budget you’re okay.

Sorry, I was thinking if Johan had done profiling for his game. :slight_smile:

Yes I have done extensive profiling and the performance hit is really big, especially on older mobile devices. Now we have refactored all behaviours into modules and it is much faster, but as @britzl says it makes the code much harder to read.
I like your suggestion with separation into two game objects. Shouldn’t it be possible to just set one as a child to the other? Or will the messages still be passed to both?

Ok, good you’re getting performance under control. There are some ideas floating around here about how to improve message passing performance, but no definite plans yet.

Childing only affects the scene-graph so yes, you can set one GO as child to another without problems.