Could not send message 'message' from 'A' to 'B'

Its a simple quiz game. Player answers the question and answer is shown. Uses Monarch screen manager and Druid UI. Project structure is:

  • main
    – screens
    — answer.collection
    — answer.gui
    — answer.gui_script
    — quiz.collection
    — quiz.gui
    — quiz.gui_script

in quiz.gui_script i have:

local function on_answer_button_callback(self)
msg.post("answer:/screen#gui", "answered", { answer_explanation = "ANSWER!" })
end

and in answer.gui_script

function on_message(self, message_id, message, sender)
    monarch.on_message(message_id, message, sender)
    self.druid:on_message(message_id, message, sender)
    
    if message_id == hash("answered") then
        local _answer_explanation = message.answer_explanation
            
        local answer_explanation_text_node = gui.get_node("answer_explanation_text")
        gui.set_text(answer_explanation_text_node, _answer_explanation)
        
        print("Received answer_explanation:", _answer_explanation)
    end
end

Problem is, message is not passed from one script to another ie. quiz.gui_script to answer.gui_script. Always get error message: Could not send message ‘answered’ from ‘quiz:/quiz#screen’ to ‘answer:/screen#gui’.

IDs for collections are correct - “quiz” and “answer” with “screen” game object with “gui” in both colelctions

Put a print(msg.url()) in the init function of your answer.gui_script and confirm that it does indeed match “answer:/screen#gui”.

debug_screengui

Could it perhaps be that the message posted before the answer-collection is fully loaded?

2 Likes

Maybe, still learning Defold. Which function should be used for load delay? This is whole button callback:

local function on_answer_button_callback(self, button_instance)
    local button_data = button_instance:get_data()
    
    if button_data then
                
        if button_data.is_correct then
            print("CORRECT ANSWER!")
            button_instance:set_answer_texture(true)
            monarch.show(hash("answer")) 
        else
            print("INCORRECT ANSWER.")
            button_instance:set_answer_texture(false)

            for i, answer_button in ipairs(self.answer_buttons) do
                local abtn_data = answer_button:get_data()
                if abtn_data.is_correct then
                    print("--- SHOW CORRECT ANSWER --")
                    answer_button:set_answer_texture(true)
                    monarch.show(hash("answer"))
                end
            end
        end
        -- disable answers after user click
        for i, answer_button in ipairs(self.answer_buttons) do
            answer_button:set_enabled(false)
        end

        msg.post("answer:/screen#gui", hash("answered"), { answer_explanation = "--SAMPLE DATA--" })
    end
end

This is an asynchronous operation. The screen will not be immediately available since it might take time to load resources etc.

The function does take a callback which is invoked when the screen has been fully shown, so you could use that. Example:

local options = nil
local data = nil
monarch.show(hash("answer"), options, data, function()
    msg.post("answer:/screen#gui", hash("answered"), { answer_explanation = "--SAMPLE DATA--" })
end) 

Another option you have is to pass the “answer_explanation” as data to the screen, like this:

local options = nil
local data = { answer_explanation = "--SAMPLE DATA--" }
monarch.show(hash("answer"), options, data) 

And then in your answer screen you can read the data:

-- answer.gui_script
function init(self)
    local data = monarch.data("answer")
    print(data.answer_explanation)
end
4 Likes

Tnx both, yes, it was async problem. Screen didnt load fully to apply text. Using msg.post in monarch.show function parameter also didnt performed as expected, loading (applying) text after 1 second delay, showing visible old text on screen for a second. However, using monarch.show and setting data within parameter and accessing it in another gui script after screen was fully loaded, with monarch.data function worked perfectly.

1 Like