Radiant.call versus radiant.call_obj?

I would like to object the phrasing a bit. You’re not calling something “by” an object, you’re calling something on an object. It’s a method invocation.

radiant.call_obj('stonehearth.inventory', 'get_inventory_capacity_command') is basically stonehearth.inventory:get_inventory_capacity_command() in lua (is the same as stonehearth.inventory.get_inventory_capacity_command(stonehearth.inventory)). stonehearth.inventory is a service (the inventory service) of the stonehearth mod, registered on the server side by SH itself. If I had to wage a guess, you could access at least mods and their direct fields that way, but it could probably work for all global variables.

radiant.call is able to call pre-defined functions in the manifest (the functions part of it) on either server or client side (originally very popular for commands) and is the usual, generic go-to way to communicate with the lua side from JS (and, to some extent I suppose, from the client to the server. Not sure if vice-versa is a good idea anymore).

radiant.call_obj is able to call it on some object (object_commands) and is seemingly server-only, but able to directly invoke methods without needing a specialised function method.

There’s advantages and disadvantages to each of them:

  • If you’re doing a quick query, or a simple command, and you already have a service/controller in place that also happens to have just that method already in use somewhere else (on the lua side), call_obj can simplify things a lot.
  • If you’re trying to call something on any lua object in general, radiant.call_obj can be useful because it avoids writing boilerplate code for the callback. That only works if you have the reference of course - if you need to find the object somewhere, it might be quicker/easier to write a normal radiant.call callback instead.
  • If you need more advanced promise resolution (e.g. your action could take some time before you can return a result, or you need to be able to fail in a specific way, or maybe report progress), then a callback function with radiant.call (which might just be a wrapper) would be the way to go. Examples would be the whole selector business, which need to prepare some bits in lua, then wait for the GUI to do the selection, then do some more lua, and then return with success/failure (I think, it’s been a while).
  • If you need to call something on the client, then it’s (seemingly?) always radiant.call

When in doubt, use radiant.call and write a callback method. You can’t really go wrong, and in the worst case, you’ll just write additional code.

5 Likes