Requirements for communication in Defold:
- Asynchronous lock-less communication between systems
- Everything should be able to address anything, at any time
- Relative addressing - to be able to reuse logic structures
- Unified across the engine
- Data should be tightly packed for known content, but also support arbitrary user data
Message passing and URLs is a solution to these requirements.
The goal was not to describe it in 3 sentences (that’s a strange rule), the goal was to solve problems.
Game objects and scripts
A game object instance is nothing but a spatial transform and the grouping of several components (which in turn are instances in other systems, e.g. sprites). The grouping itself constitutes its “class”. We regard game objects as “tiny systems”, or “units”, in the classic sense of object orientation which is not the same as modern object orientation (inheritance, OOP, etc.). This is because they benefit from being loosely coupled, as games are often unknown and it’s important to be able to make significant changes. Modern OOP creates tight couplings and work agains this, forcing you to change more of the source than what you intended to change. You are not forced to express your game logic through message passing though, you can still use lua and function calling etc. to any extent. If you think of your game in a MVC/MVP kind of way, this would correspond to doing the Model/Controller part in arbitrary lua and the view part using game objects. I would advice against this from the tight couplings it would introduce.
When to not use message passing
When the data being communicated is large in size, e.g. level data. Since message passing is asynchronous, the memory needs to be copied. It’s better to use the global state in these cases.
Problems and improvements
- Auto-complete makes function calls way better than messages, for documentation purposes. This is why we have started to introduce functions which simply wraps messages. You can certainly do this yourself for any user-defined messages being posted, like @britzl suggested.
- It’s annoying to lose the context when you have to wait for a response. Agreed! We could look into adding callbacks for message passing, so you could easily create a closure of the context for a response. Speaking of callbacks, we have some bugs in how they are invoked when you lose the lua context when dealing with coroutines etc. They of course need to be fixed too.
@deeeds What’s important is not how you think of messaging but if you solve the problems or not. I think you should ask yourself if Defold really is a good fit for you. If you still think it is, we are happy to explain more about why things work the way they do.