Modified Dispatcher module based on Secure-Cast.
Note
The original version can be found here: https://github.com/1Axen/Secure-Cast/blob/main/src/Dispatcher/init.lua
VMsDispatcher is a parallel scripting module designed to make multi-threading across multiple Actors easier and more manageable.
It abstracts Actor communication and workload distribution, allowing you to dispatch tasks across worker threads efficiently.
-
Load balancing: Uses a "Tasks" attribute on each Actor to track workload and routes new tasks to the least busy worker.
-
No dependency on SharedTable (when used correctly).
-
Designed to be highly customizable.
Different implementations of VMsDispatcher can be adapted to suit various system architectures and use cases. Example — FastCast2In FastCast2, a specialized implementation called
FastCastVMsis used as the template. WheneverCaster:Init()is called, it clones theFastCastVMstemplate and initializes the required parallel actors dynamically.This demonstrates how VMsDispatcher can be embedded inside larger systems and tailored to their architecture.
Read more: https://weenachuangkud.github.io/FastCast2/api/BaseCast#Init
Create a LocalScript or Script inside any container (Folder / Model).
Name it VMrunner (or any name you prefer).
You can write your own implementation — copying is optional.
-- Requires
local ClientVM = require(PathTo.VMsDispatcher)
-- Test
local numWorker = 4
local dispatcher = ClientVM.new(numWorker, nil)Your Explorer tree should look like this:
Container (Folder / Model)
│
├── VMsDispatcher (ModuleScript)
├── ClientVM (LocalScript)
└── ServerVM (Script)
Warning
ClientVM and ServerVM must be disabled, or they will not work properly.
Inside ClientVM or ServerVM, paste this test code:
local RS = game:GetService("RunService")
local Actor = script:GetActor()
if not Actor then return end
Actor:BindToMessage("Init", function(MS : ModuleScript?)
Actor:SetAttribute("Tasks", Actor:GetAttribute("Tasks") + 1)
RS.Heartbeat:ConnectParallel(function()
debug.profilebegin("VMworker" .. tostring(math.random(1,100)))
for i = 1, 10000 do
i = i*i*i
end
debug.profileend()
end)
end)Inside VMrunner, add:
local message = "DOTASK"
while task.wait(0.1) do
dispatcher:Dispatch(message)
endInside ClientVM or ServerVM, replace the previous code with:
local RS = game:GetService("RunService")
local Actor = script:GetActor()
if not Actor then return end
local message = "DOTASK"
local AMOUNT_OF_WORK = 1000
Actor:BindToMessage(message, function()
Actor:SetAttribute("Tasks", Actor:GetAttribute("Tasks") + 1)
local i = 0
local connection
connection = RS.Heartbeat:ConnectParallel(function()
i += 1
if i == AMOUNT_OF_WORK then
connection:Disconnect()
connection = nil
Actor:SetAttribute("Tasks", Actor:GetAttribute("Tasks") - 1)
end
end)
end)If everything is set up correctly:
- Open MicroProfiler with:
Ctrl + Window + F6 - Hover over a frame.
- Press
Ctrl + P.
You should see multiple separated worker threads (e.g., 4 threads if numWorker = 4).
MicroProfiler reference image:
Microprofiler
VMsDispatcher is used by FastCast2 to provide an API that allows users to easily allocate and manage threads through initialization.
It abstracts thread handling, making it easier for developers to distribute workloads without manually managing low-level threading logic.
FastCast2 extends and modifies VMsDispatcher to integrate it into an initialization-driven API architecture.
For a usage example, see:
https://github.com/weenachuangkud/FastCast2