Parallel LUA: How to get data back from an actor?

I’ve been exploring the use of multiple threads in my game and I have found a problem. It seems that using the Actor Messaging API has some flaws. Namely, I can send data to an actor, but there doesn’t seem to be a way to get results back without jumping through some hoops.

Granted, if I want it to do something and don’t care about the results, this works. But if I’m performing a status query, there doesn’t seem to be a way to bring the data back out of the actor unless I use a shared table where I specify which keys to look for the result.

Unless someone has a better idea of dealing with this, parallel LUA isn’t going to work for my game very well.

2 Likes

Encountered a similar problem myself and what i used was coroutines that run arguments. To send in values my janky solution would just be to use values unless actor messaging api has support for coroutines.

here is a post I found with someone explaining coroutines better than i can

I couldn’t figure out the coroutines method that you mentioned. However, I have come up with an alternate solution: Bindable Functions.

With a bindable function, you can pass data between the LUA interpreter instances for each actor. There are limits to what data can be passed, but I’m not really doing anything too crazy, so I can live with those limitations. So to make usage simple, I have a folder under the actor that holds the BindableFunction instances. I also have a module script that get’s copied into an include folder when the main script runs. The module script contains all the references to the bindable functions in a normal function call format in which all functions invoke the approperiate function which on the other end calls the function inside the actor.

The include (module) script

local packageName = "Some Package"

local serverScriptService = game:GetService("ServerScriptService")
local actor = serverScriptService:WaitForChild(packageName)
local public = actor:WaitForChild("Public")

local function SomeFunction(param1, param2)
	return public.SomeFunction:Invoke(param1, param2)
end

The handler script inside the actor.

local packageName = "Some Package"

local serverScriptService = game:GetService("ServerScriptService")
local actor = serverScriptService:WaitForChild(packageName)
local public = actor:WaitForChild("Public")

local someModule = require(actor.SomeModule)

public.SomeFunction:OnInvoke = someModule.SomeFunction

And that’s it.