Why does Defold not use the observable pattern?

I’m just beginning to learn Defold and it seems to me that the message passing system, while good in a lot of ways, also results in a lot of boilerplate. I’m a JS/TS developer with no experience in lua yet so I may have missed something here.

It seems to me that scripts in Defold repeat the same pattern over and over. Script 1 has a piece of data and script 2 needs to know when it changes. This is the message passing pattern

  1. Script 1 creates a piece of data
  2. Something causes data to change on script 1, we write code that posts a message to script 2
  3. Script 2 implements on_message to handle the message about the changed data coming from script

This bit of boilerplate where script 1 explicitly passes a message to script 2 could be replaced much more cleanly with the observable pattern. That would look like:

  1. Script one creates an observable piece of data
  2. Script two (and possibly many others) observes that piece of data and is notified when it changes.

This is the pattern I use all the time in JS with Mobx (and mobx-state-tree). In JS with mobx the pattern is even nicer – mobx automatically tracks which pieces of data have been referenced in an observed function and re-runs it when any of that data changes. You don’t even have to specify which pieces of data to observe, it tracks that automatically and on first use it feels like magic but it’s also extremely efficient.

It seems like a mobx style observable pattern would be a perfect fit for Defold to reduce seemingly tedious message passing boilerplate. I’m new to Defold and lua so I’m probably missing something. Is there a reason this pattern isn’t used?

2 Likes

You do have the option to create lua modules for data that can be accessed from various scripts. This may be more like what you’re used to.

2 Likes

You can implement an Observer pattern as well as Publisher-Subscriber pattern :wink:

Check how you can use modules:

There is an event based broadcasting system by @britzl:

Ludobits - broadcast

There is also a nicely implemented dispatcher by @dapetcu21:

Dispatcher

Check also:

http://lua-users.org/wiki/ObserverPattern

I found also:

4 Likes

Thank you! Very interesting stuff.

In an effort to learn more about lua and see how my JS/TS knowledge translates I was able to whip up a little “mobx like” module. As a proof of concept I can wrap a piece of data with observable like observable({foo = "bar"}) and wrap a function in observer then have that function rerun anytime foo is assigned a new value on that observable.

An example:



function test()
        -- could be anywhere in your code
	local obs1 = observable({foo = "bar", baz = 123})

        -- could be anywhere in your code, it just has to access
       -- a property on an observable object (err, I guess it's a table in lua)
        local reactive1 = observer(function ()
                print("reaction1: foo is " .. obs1.foo)
	end)


      -- once the function has run all of its "dependencies" 
      -- are automatically recorded
	reactive1()

       -- this could be anywhere in your code 
       -- and it will cause reactive1 to run again!
       -- no need for explicit 
	obs1.foo = "react to me!"
end

This will print

reaction1: foo is bar
reaction1: foo is react to me!

This pattern lets you react to changes in data without explicitly setting up a message for each and every data change. It doesn’t even require using any explicit API for each thing you react to – just write a function (wrapped in observer) and it automagically re-runs anytime any of the referenced observable properties (but nothing else) changes. In the example above if you set obs1.baz = "asdf" then reactive1 would not run again.

My little proof of concept definitely isn’t usable at the moment. It’s lacking (all the) features and probably has memory leaks, but it illustrates that the mobx style reactive pattern is possible in defold/lua!

I should probably get on with actually learning how to use the engine now instead of messing with state management code haha

3 Likes

Great! :tada:

Moreover, I think you might be interested in this Typescript to Defold project :wink:

3 Likes

That TS to Lua project looks neat, but I’m guessing that in that direction lies a lot of pain. It seems likely to me that any language transpiled to lua for use in Defold is likely to end up running into severe and difficult to debug performance problems. Do you know of anybody actually using that transpiler in a real game?

3 Likes

Not me :confused: might be good to ask on that thread :wink:

P.S. And regarding your questions about obvservable patterns - is it enough for you? :blush:
You can mark questions (SOLVED) by just editing the title is is helpful on the forum :wink:

1 Like

Unfortunately it looks like that TS to Lua for Defold project is abandoned and no longer works. TS to Lua no longer outputs Defold friendly code it seems. Would require some tinkering to get it working again.

Edit: ah it looks like ts to lua doesn’t support a lot of core js/ts features – for example no support for promises which means a lot (most?) npm modules likely wouldn’t work. Neat idea but seems like it can’t really work in practice https://typescripttolua.github.io/docs/caveats

2 Likes

I’ve been casually looking for a decent Lua tech stack for about about a week now.
Using RxLua and Ravi(sort of like what TS is to JS) in combination could be used for similar workflow/coding experience to the one in modern Web development.

Something like Terravi(Terra + Ravi) combination could be interesting: Lua based syntax for Low and High level programming.

The other option would be using Haxe, which would require more Language specific context switching.

1 Like

Welcome to the Defold community. In case you haven’t seen this information before, this is the pattern that Defold uses: Entity Component System (ECS). If you are not familiar with using it, I suggest you take some time to understand it first. You may end up preferring it for game development over Observer pattern.

Rxlua is cool. Use it in my projects))

Defold not use ecs. It is component pattern. Like in other engines.

1 Like