How many messages can a script receive each frame? (SOLVED)

Hi, I have this doubt beacuse I dont know how is the best way to code

if message_id == hash(“message1”) then
stuff
elseif message_id == hash(“message2”) then
stuff
elseif message_id == hash(“message3”) then
stuff
end

or

if message_id == hash(“message1”) then
stuff
if message_id == hash(“message2”) then
stuff
if message_id == hash(“message3”) then
stuff
end

Because I dont know if its possible that a script receives more than 1 message each frame.

thanks

Hi Vik,
the engine will dispatch more than one message on each frame, but keep in mind that there’s a limit on how many will be actually dispatched.

You can verify this yourself using the code provided on the “Message chains” paragraph on this page: Message passing in Defold.

function init(self)
   -- We’re starting a long message chain during object init
   -- and keeps it running through a number of update() steps.
   print("INIT")
   msg.post("#", "msg")
   self.updates = 0
   self.count = 0
end

function update(self, dt)
   if self.updates < 5 then
       self.updates = self.updates + 1
       print("UPDATE " .. self.updates)
       print(self.count .. " dispatch passes before this update.")
       self.count = 0
   end
end

function on_message(self, message_id, message, sender)
   if message_id == hash("msg") then
       self.count = self.count + 1
       msg.post("#", "msg")
   end
end

Running this script will print something like the following:

DEBUG:SCRIPT: INIT
INFO:ENGINE: Defold Engine 1.2.36 (5b5af21)
DEBUG:SCRIPT: UPDATE 1
DEBUG:SCRIPT: 10 dispatch passes before this update.
DEBUG:SCRIPT: UPDATE 2
DEBUG:SCRIPT: 75 dispatch passes before this update.
DEBUG:SCRIPT: UPDATE 3
DEBUG:SCRIPT: 75 dispatch passes before this update.
DEBUG:SCRIPT: UPDATE 4
DEBUG:SCRIPT: 75 dispatch passes before this update.
DEBUG:SCRIPT: UPDATE 5
DEBUG:SCRIPT: 75 dispatch passes before this update.

thanks

You should do the first version, with elseif. One script can get many messages every frame, but the on_message function will be called for each one. You don’t get multiple messages in one function call.

Your second piece of code with only ifs is just wrong. If you write it with proper indentation, it looks like this:

if message_id == hash(“message1”) then
	stuff
	if message_id == hash(“message2”) then
		stuff
		if message_id == hash(“message3”) then
			stuff
		end

As you can see there are two missing ends, and the second two conditions will never happen because they are inside the first one.

If you correct it in one possible way, you get this:

if message_id == hash(“message1”) then
	stuff
end
if message_id == hash(“message2”) then
	stuff
end
if message_id == hash(“message3”) then
	stuff
end

This would work, but it’s very inefficient because it will check every single condition even after it finds the correct one.

4 Likes

If you have many messages, would be better don’t call the hash() methods every time when you receive a message:

local MSG_1 = hash("message1")
local MSG_2 = hash("message2")
local MSG_3 = hash("message3")
...
function on_message(...)
  if message_id == MSG_1 then
  -- stuff
  elseif message_id == MSG_2 then
  -- stuff
  elseif message_id == MSG_3then
  -- stuff
  end
end

Sometimes it’s more convenient to have something like:

--lua module with your messages, to be sure that you won't do typos and so on
local M = {}

M.MSG_1 = hash("message1")
M.MSG_2 = hash("message2")
M.MSG_3 = hash("message3")

return M
local msgs = require "path.to.the.lua.file.above"
...
local function stuff_1(self, message)
   -- stuff
end

local function stuff_2(self, message)
  -- stuff
end

local function stuff_3(self, message)
  --stuff
end

local this_script_functions = {
  [msgs.MSG_1] = stuff_1,
  [msgs.MSG_2] = stuff_2,
  [msgs.MSG_3] = stuff_3
}
...
function on_message(self, message_id, message)
  if this_script_functions[message_id] then
    this_script_functions[message_id](self, message)
  end
end
3 Likes

@ross.grams @AGulev thanks both