Defold message passing discussion

Now I’m curious. Would you mind posting your feedback or improvement suggestions regarding the messaging system?

5 Likes

Try to explain Defold messaging in less than 3 sentences, such that anyone, from any knowledge base, can understand it.

If you can do that, there’s no need to change it.

You send messages to things based on addresses which can be relative or absolute in terms of pathing. When something checks its message inbox only it can decide what to do based on the data of the message. Messages are processed multiple times per frame.

1 Like

I’m none the wiser as to how to do it. You’ve only explained WHAT it can do, not how, nor why, when or where.

eg. Mail messaging, to send a message to your friend, via post:

Write his name, and address, on the front of an envelope, and your address on the back. Place your message inside the envelope. The send address should be of the format:

firstName - Surname
House Number on Street
of Suburb…
in the City…
Belonging to the State of…
Of PostCode…
In the Country of…

Be sure to fill out your return address in the same format, on the back.

What, where, when, how, why would be at least five sets of three sentences each minimum wouldn’t it?

What: Messages are a way of sending information in a way that is loosely coupled. Messages can have a name/id and a body. The body can be any kind of Lua table, but has a max size in bytes.

How: Most scripts can send messages with the msg.post(address, message_id, message_lua_table_data) syntax. Game Object, GUI, and Render scripts can check their inboxes based on the on_message(self, message_id, message, sender) function. You can place conditional statements in your on_message functions to select for message id, as well as the contents of a message, to decide how to act on them.

Why: Defold is designed in a loosely coupled way in an attempt to avoid the occurrence of bugs caused by tightly coupled dependencies. Instead of acting directly, you can send a message, and then other entities can choose to act on the message or not. Communicating with the system is often done through message passing, communicating with child / parent objects, such as children telling their managers that they were created, or parents telling their children to die.

When: Messages are processed every frame multiple times. Unless you are generating a very large number of messages most which are generated on a frame will be processed. When a thing gets a message it will also get the path to its sender in case it should want to reply.

Where: You do not want to use message passing for everything. Some kinds of data you should pass through shared imported modules. Some kinds of entities you want to control via a master object with a single controller script, and to not have each thing its controlling having its own logic.

Better?

6 Likes

Only if message sending is an inelegant mess.

You are asking for five things to be explained in three sentences…

2 Likes

No, just message sending.

Ok, I feel I’ve explained that simply above already with the how section. Explaining 5 things (what, where, when, how, why) is still a challenge in three sentences, but I could cheat and make them long sentences?

Can you explain exactly what you don’t like about Defold message sending system? Is it the address pathing you are having trouble with understanding?

Can you explain how Defold’s system could be changed to look more like an elegant solution? Is it more tight coupling, direct modification that you’re after?

This tangent would have been better in its own thread…

1 Like

Objective-C

[object message:parameter]

Once you accept that there’s NOTHING elegant about how Defold handles messaging, you’ll begin to see the problem.

JavaScript

Object.subObject.function(parameter, parameter02)

Swift

typeName.subTypeName.function(argumentLabel: parameterValue)

I can’t think of a single language or framework that does it as horribly as Defold. Can you?

1 Like

of this: msg.post(address, message_id, message_lua_table_data)

What does an address look like?

What does a message ID look like?

How is a message lua table data “packet” actually structured?

I ask, because my above examples are exactly how their code looks, in all those languages, bar the horrible names I’ve used.

However you’ve not even used placed holders. You’ve used descriptors to hide how inelegant actual use of Defold messaging is. Show a REAL example, with full address, and a parameter, and a function name.

What does an address look like, and what is it relative to in Defold?

How does it trawl the system to find this address?

I explained things the way I did only because I was trying to answer your questions based on what I thought you were after.

Those examples are tightly coupled, are they not? Defold is intentionally designed in a loosely coupled way, like Erlang, for the benefits that this gives in designing your systems.

You do not call functions directly in message passing, but you can setup the recipients to act on messages as if they had functions called directly on them.

You can call functions directly with required modules. This may be more closely to what you are after depending on what you are trying to do.

Here is a basic example to compare to yours.

msg.post(“object_collection/sub_object#component”, “function”, { “parameter”, “parameter_02” })

Defold would expand the above relative path in a way that is relative to where the script calling it lives. The message labeled “function” wouldn’t actually be a direct function call, it’s just a label for the recipient to filter based on.

And here is maybe an example that may happen if you have a script in a different socket that wishes to send a message to something in the main socket world in a hard coded way.

msg.post(“main:/sub_collection/player#logic”, “increase_score”, {score_to_add = 200})

Do you know what a Lua table is? The data is just a Lua table. You can make it any way you want mostly. An exception is you can’t pass anonymous functions.

Pathing is a different subject. You can define paths into variables to be reusable. The paths are based on a scene hierarchy from the socket (the world the recipient is in) through a path leading through possible collections until you reach a game object / its component you wish to communicate with. You can define an address in a relative way or an absolute way. If you define it in a relative way then Defold will build the rest for you based on where the entity defining the path is at.

How does it trawl the system to find this address?

Again, if you define the path in a relative way, it will look at the position of the current script calling msg.post and try to construct the path dynamically.

Did you read the official docs on message passing already? http://www.defold.com/manuals/message-passing/

4 Likes

This looks more like calling a specific function on another object. Does this mean that you prefer a system where you can call any function on any other object without limitations? Also, are you not omitting some things from your examples above? Take objective-c for instance:

[object message:parameter]

What is object here and how do I get hold of a reference to it? Another thing that comes to mind is that you are comparing language features in Objective-C, Javascript and Swift with those of a game engine framework (in this case Defold). Wouldn’t it be more fair to compare the three programming languages Objective-C, Javascript and Swift with the Lua programming language and not with the game engine Defold?

Also, what we are doing here is theoretical. It would be better if we could come up with a real world example of when to use message passing and discuss around that specific example.

5 Likes

How does it trawl the system to find this address?

Addresses are static.

2 Likes

Our message passing and URLs is modeled after the internet and HTTP, because the requirements we designed after were quite similar to those systems. A programming language is something completely different, and solves different problems.

5 Likes

Deeeds, I am confused as to what your confused about because the messaging system seems incredibly straightfoward. Ignoring your opinion on the “elegance” of the system, I have a few questions for you that will help us understand better.

  1. What specifically do you not like about the messaging? Vague generalizations aren’t helpful. If you don’t have any specifics, do you just not understand how the messaging works at a high level? And did the documentation not help with your understanding?

  2. What are you trying to do that you can’t accomplish with this messaging system?

  3. What future or hypothetical situatioms do you believe can’t be accomplished with this messaging system?

  4. Do you actually understand how the system works in general and don’t have any specific problems that need to be solve and are mostly hoping to get a peak at the implementation details of the messaging system?

3 Likes

I personally just think that using messages for what Defold is using them is a pointless complication. Why not just use functions and hooks for everything that is done with messages now?

Message-heavy architecture could make sense if we’d use them to communicate between runtimes or different machines. But now everything is sitting in same runtime, can give each other direct access to self through global variables and functions etc.

1 Like

There is nothing preventing you from setting up a system like that for your own code through Lua modules. But for Defold as a whole the design decision was made a long time ago to use message passing as the way to communicate between game objects and components (and as you probably can understand it is nothing that can be changed now).

Why? You can have both

msg.post(".", “set_parent”, {parent_id = self.master})

and

go.set_parent(self.master)

with one of them being a (possibly deprecated) wrapping around another.

1 Like