trying to get the most performance out of my game, and since some of the functions in my structure could yield, take long, etc., I want to avoid that by trying to multithread.
But I am confused on what to do. Using only one client actor, you’ll only get two threads (main and one extra), and I believe that putting a module script under an actor will cause it to return a different table for each thread, which is not optimal.
Is there a way to properly multithread with single-script architecture or is it just not possible?
First, it is important to understand the difference between concurrency and parallelism.
In a sense, coroutines are a form of multithreading because they allow you to conceptually run two separate functions at the same time. In practice, the VM is just alternating between executing each thread.
Each Roblox script runs on its own thread. When you require a module for the first time, it executes the module on the caller script’s thread and caches the return.
Parallelism, on the other hand, is truly executing two functions at the same time. Depending on the platform and whatever the Roblox engine decides on, parallel threads may be executed on separate VMs on different processors or revert back to behaving like normal coroutines.
The performance benefits of parallelism even outside of Roblox is very context critical. Since manipulating memory between processes at the same time is inherently unsafe, there are many bottlenecks to prevent you from doing something dangerous. That’s why you can’t pass functions over VMs, because they wouldn’t work properly.
Personally, I believe the way Roblox provided parallelism is by all means incredibly stupid. In real game programming, you’re going to be working with a lot of state, and parallelism is antithetical to state. The only cases where parallelism may perform better than traditional methods is when you’re interacting heavily with Roblox’s API, and even then, you’re getting micro-optimization levels of improvement.
So yes, you can utilize multithreading in single-script architecture (using task.spawn and events), but you cannot utilize parallelism and generally shouldn’t.
Without technical details about how your game is structured, you won’t get a satisfactory response here. If you already understand the basics of co-routines and task spawning, you would need to take a more global look of your game structure and how the game logic works if you want to improve performance, etc.