Message Sending Troubles

Hello,
I’m just starting with Defold and I’ve finished all the tutorial projects. For the Colorslide tutorial, I’m trying to add dynamic text to the level gui to better understand message sending.
In the loader.script, I modified the on_message “load_level” behavior as follows

if message_id == hash("load_level") then
		self.current_level = message.level
		local proxy = "#proxy_level_" .. message.level
		msg.post(proxy, "load", { level = message.level })
		msg.post("default:/loader/proxy_level_" .. message.level .. "/level#gui", "set_level_text", { level = message.level })
	elseif ...

but after building and selecting level 1, I get the error

ERROR:GAMEOBJECT: Instance '/loader/proxy_level_1/level' could not be found when dispatching message 'set_level_text' sent from default:/loader#loader

I’ve read the message and address manuals, and I’ve tried many possibilities for addresses

"proxy_level_" .. message.level .. "#gui"
-- 
"default:/loader/proxy_level_" .. message.level .. "#gui"
-- 
"proxy_level_" .. message.level .. "#gui"
-- 
"default:/level_" .. message.level .. "/level#gui"
-- 
"level_" .. message.level .. ":/level/#gui"

I get similar errors to the above or errors like this one

ERROR:SCRIPT: /main/loader.script:21: Could not send message 'set_level_text' from 'default:/loader#loader' to 'level_1:/level#gui'.

Any help figuring this out, and figuring out addresses in general would be greatly appreciated.

I haven’t done or seen the finished version of the Colorslide tutorial so I’m not sure of the exact setup. But it sounds like you want to post a message to a gui in a collection that gets loaded via a proxy?

If that’s the case then you need to post to a url looking something like this:

"id_of_collection:/id_of_go#id_of_gui"

Thanks for the help.
I just tried to use that url pattern by doing

"level_" .. message.level .. ":/level#gui"

and got the error

ERROR:SCRIPT: /main/loader.script:21: Could not send message 'set_level_text' from 'default:/loader#loader' to 'level_1:/level#gui'.
stack traceback:
	[C]: in function 'post'
	/main/loader.script:21: in function </main/loader.script:16>

I’ll upload the project as I have it now incase I’ve done something strange that’s preventing this from working.
The area I’m having trouble with is in loader.script’s on_message function.
edit: I guess the whole project at just under 15MB is too large, so here’s the main folder.
main.zip (15.0 KB)

Can you somehow try and share the entire project? Dropbox or Google Drive. Or if it’s a dashboard project you can invite me (Bjorn.ritzl@king.com). If you zip it then remember to exclude the .git .internal and build folders.

Here it is
Colorslide

Have you resolved this issue? I’m running into the exact same thing, where messaging from the loader.script that lives in the main.collection -> #gui that is inside a collection proxy called “level_1”

Is the proxy component called ”level_1” or is the collection id of the loaded collection set to ”level_1”?

as following the tutorial, proxy component id is “proxy_level_1” and the name of the collection in the loaded proxy is “level_1”

i have confirmed that the loaded level + gui i’m trying to message is located at level_1:/level#gui (by sending a message from #gui and printing the sender), but messaging it from default:/loader#loader results in the error

ERROR:SCRIPT: /main/loader.script:15: Could not send message 'level_loaded' from 'default:/loader#loader' to 'level_1:/level#gui'.
stack traceback:
	[C]: in function 'post'
	/main/loader.script:15: in function </main/loader.script:10>

Related question, what is the difference between the “Could not send message” vs “Instance could not be found” errors? The latter one I understand, but what does “Could not send message” actually mean?

So this probably isn’t the ideal solution, but I hypothesized that I was getting the error above because the proxy wasn’t actually loaded yet. I was sending the message right after sending the message to load the proxy, like so:

	if message_id == hash("load_level") then
		self.current_level = message.level
		local proxy = "#proxy_level_" .. self.current_level
		msg.post(proxy, "load")
		msg.post("level_"..self.current_level..":/level#gui", "level_loaded", { level = self.current_level })

I’ve hacked around it by sending a message from the init() call of the level, back to the loader, which then sends the message to the #gui. This works, but there is a slight delay to the Level title changing. After you change levels, the new level renders, but the title is briefly the previous level (e.g. “Level 1”) before it quickly changes to the next title (e.g. “Level 2”). Either because the level.script init() call happens after the proxy level draws or because sending messages is async and there’s no guarantee that the level title text will change in the GUI before the proxy level is loaded

Additional information for future discussion, my setup is:

main.collection
> loader
>> loader.script
>> proxy_level_1
>> ...

level_1.collection
> level.go
>> level.gui
>> level.script

Well, if you wish to wait until the level is loaded: (from the doc)

function on_message(self, message_id, message, sender)
    if message_id == hash("proxy_loaded") then
        -- New world is loaded. Init and enable it.
        msg.post(sender, "init")
        msg.post(sender, "enable")
        ...
    end
end

3 Likes

Wow, okay, yea that’s exactly the solution…

Thank you ! I feel like a big dummy :slight_smile:

2 Likes