Just curious and wanted a better understanding because Defold is pretty unique in how it and it’s message system is designed along with it’s use of a multi-paradigm language. So if someone who had never used Defold asked you “What kind of architecture is used to handle the game logic?” how would you answer?
Event driven
As @DeManiac writes the recommendation is to leverage events and write reactive code. This means that you should:
- Let the engine do as much work for you as possible. If you have a choice of animating manually per frame in update() and calling for instance go.animate() then you should use go.animate() for performance reasons.
- You should write code that reacts to events as much as possible. The callback of a go.animate(). The callback when a sprite animation has finished. The message you get from the system when a collision has happened. The message you send from another part of your code, for instance when a score counter needs to be updated.
Another thing that differentiates Defold is in the fact that it does not encourage object oriented principles. The recommendation is to try and keep all your data in one place and think about data transformation and how that affects the state of your game. Don’t try to spread you game data over many scripts in an attempt to replicate oop practices. Sure, go.property() values exist and can be used, but be careful. If you find yourself doing a lot of go.get() and go.set() to get and set data every frame then you probably should consider collecting the data you need in one place.
One of the reasons I asked was to develop good programming habits, and write smarter code so it’s like you read my mind then answered as such.
Would you at all consider defold to have some sort of an entity component system like approach? Ive recently been looking into what those are after seeing one or two people mention it here and there in the defold forums. After looking into what they are a little, what I understand is that most times these entity component systems are typically data driven rather than event driven. So if defold doesnt really have any sort of entity component system implemented, what are the benefits or disadvantages to the event driven approach that Defold has taken versus using something like an entity component system?
Edit: Revised some of my poor 5am wording.
Entity component systems are great when you perform repetitive tasks on a large amount of data, to cut down on cache swap and garbage collection. You can still separate your code in entity data, components of such and systems manipulating them, but… the big benefit of Defold is that you can leverage the engine to do that work for you. The go.animate works like aforementioned systems, manipulating the entity value you pass in, but doing so in the C/C++ layer instead performing many times faster than a similar system would do in Lua.
In similar fashion you should always try to leverage the provided systems. The input system, physics and all of these are following similar design, where large calculations happens in systems beneath the hood and you simply receive the events spawned from that.
When you msg.post, you add that to a buffer which will later be processed so all messages can be handled at once. This however creates a deferred architecture, meaning that after doing the post, nothing happens on the target immediately, this can sometimes force you to move code you expected to run on the line after, to the target or inside a response callback instead.
eg,
msg.post(target, “die”)
if unit_manager.units_alive() <= 0 then
print(“victory”)
end
Here you should move the alive check to the target instead, cause the target would not yet be dead. Only after the message has been processed by the system, passed to the target and the function been invoked would you have the final result.
Just like Adam says, you can view the Defold engine as one big ECS system. The engine spends most of its time every frame iterating over arrays of data and updating the data. Stepping frames of flipbook animations, animating property values (position, rotate, scale etc), spine animations etc. And generating events out to you to react to.
You could try and build something on top of the engine to use an ECS system in Lua, but the attempts I’ve seen hasn’t been great from a performance point of view. I think someone posted about this a while back here or on Slack. You should be very very careful to not build an engine on top of the engine so to speak. It’s a lot more expensive to iterate a Lua array than a C array.