Message passing and addressing

Hi all - new user here.

After reading the message passing section of the manual, I still have some issues when trying to post messages between different game objects.

My structure is as shown in the screenshot:
A collection named level, containing:

  • a game object called “level_go”, that contains a script, where I want to receive a message.
  • another collection, that represents a small numeric keyboard on screen. The logic is handled in the keypard.script, that detects key presses, animates the touched key and is supposed to post a message to the “level_go” object.

However, my addressing is wrong, resulting in no message getting sent.

I have tried:

msg.post("/level/level_go#script", "keypad_key_pressed",{key=keys[index+1],number=numeric})
error: Instance '/level/level_go' could not be found when dispatching message 'keypad_key_pressed' sent from main:/codebreaker/keypad/keys#keypad

msg.post("/level_go#script", "keypad_key_pressed",{key=keys[index+1],number=numeric})
Instance '/level_go' could not be found when dispatching message 'keypad_key_pressed' sent from main:/codebreaker/keypad/keys#keypad

msg.post("level/level_go#script", "keypad_key_pressed",{key=keys[index+1],number=numeric})
error: Instance '<unknown>' could not be found when dispatching message 'keypad_key_pressed' sent from main:/codebreaker/keypad/keys#keypad

msg.post("level:level_go#script", "keypad_key_pressed",{key=keys[index+1],number=numeric})
error: scripts/keypad.script:44: Could not send message 'keypad_key_pressed' from 'main:/codebreaker/keypad/keys#keypad' to 'level:level_go#script'

Apparently, there something here I’m not getting and I was hoping for an explanation to clear things out.

Trying to get the actual URL of my target script, I added a print(msg.url()) in its init function, and got the absolute URL:

main:/codebreaker/level_go#script

Using this to post my message to did work, but it does not allow me for any reuse of the ‘keypad’ component. My idea was to have the keypad in its own collection and use it in any collection where I want a numeric keyboard. For this, I thought I could have a “level_go” game object in all my game levels and have the keypad post messages to it. Apparently, this is not how Defold works, so maybe my question changes to:

How to post a message to a sibling of a script’s parent collection?

1 Like

I’ve used Defold for years, and I would probably still struggle to construct a URL by hand. That said, I don’t often have problems with message passing. How come? Well, either:

  1. I am dynamically generating objects, in which case I am given references when spawning via factories, which I then store in tables, or
  2. I am manually creating a single object, e.g. a controller, in which case I do what you did and stick a msg.print() in the init and use that.

It doesn’t directly answer your question of finding a sibling, but maybe that doesn’t need to be answered.

I note you’ve got keypad.script. Can you print msg.url() in there?

3 Likes

The easiest way is by printing the url of the script you want to send a message to.
Add this in the script:

print(msg.url())

I have recreated the structure of your game and added a msg.post example, maybe it’ll help you:
example.zip (17.2 KB)

3 Likes

I think the confusion lies in the difference between the file name and the address name of the collection. Those are two separate things. The file name doesn’t matter. The name of the collection that matters for addressing is in the properties panel, if you click on the “Collection” object at the top of the outline.

Having this URL:

main:/codebreaker/level_go#script

means your collection is not named “level”, it’s named “codebreaker”.

They’re in the same bootstrap collection, so you can remove “main:”. So " /codebreaker/level_go#script" should work.

Since you’re trying to go “up” one level (to access an object in the parent collection), you can’t use relative addressing. So I think you have two options:

  1. Make sure the collection is always named “codebreaker” and hard-code in that address.

  2. Since the keypad is in a sub-collection and can be addressed relatively from “level_go”, reverse the first message. Have the script on “level_go” send a message to “keypad/keys#keypad” to “subscribe” to keypad input. The keypad takes the sender URL for that message and saves it to use later (so, like Alex says, you never care what the URL actually is).

5 Likes

Thank you all for your replies - it’s nice, and even refreshing, to feel that you enter a friendly and supporting community.

I ended up, as suggested by Alex and Ross and shown by Swarkin’s example, receiving a “subscribe” message in my keypad script to get the sender url and then , if this is set, to post my keypress message there.

6 Likes