Yes* with an asterisk.
There are many different ways for different scripts to “talk” to each other. The one you need is a direct linkage between their environments, which involves either a ModuleScript or a global table _G
or shared
.
Environment linking
Using a ModuleScript is the most common way; you just need the different scripts to both require the same dummy module. You can actually do this within your module that creates the Cars! The only purpose of that module would be to store data accessible to all connected scripts.
--dummy module
local registry = {}
return registry
--that's it!
All you need to do is require this module on the scripts that need to talk to each other.
--serverscript 1
local registry = require(game:GetService("ReplicatedStorage").Dummy)
registry.hello = 'hi' --write a value to the registry
--serverscript 2
local registry = require(game:GetService("ReplicatedStorage").Dummy)
while not registry.hello do task.wait() end --wait until the other script writes the value
print(registry.hello) --print it out when the value gets written
But, using a globally accessible table such as _G
is arguably even easier. You don’t need a proxy to use it.
--serverscript 1
_G.hello = 'hi' --write a value to the global table
--serverscript 2
while not _G.hello do task.wait() end --wait for the value
print(_G.hello) --print it out
However, sadly it is taboo to use global tables in this manner. Many people have reservations against using _G
or shared
at all. Although they work similar to ModuleScripts, a pretty big difference is the lack of clarity with global tables.
ModuleScripts, being scripts themselves, allows you to write type annotations to clarify to both you and the IDE what values should be in the module. The engine can also make inferences on its own without annotations! You will never get these with _G
.
But, a major, MAJOR limitation with connecting environments is that they only work on scripts with the same execution context. Serverscripts can only communicate with serverscripts in this manner, localscripts with only localscripts, plugins with only plugins. If you want to bypass this barrier then you need a vastly different method of communication:
Out-of-script communication
If you use a different method for scripts to communicate, such as by BindableEvents or SharedTables, you need a way to serialize your object since those methods of transferring data do not like metatables among many other restrictions on datatypes. They will just delete them if you try sending the object across.
Serializing means analyzing your Car
object and packing up the valuable data into a form that can be transferred through remotes and events, where they get deserialized (unpacked) at the receiving end and gets reconstructed into a Car
object again. This is obviously tedious and complicated, but it’s what you have to do if you want to share custom OOP objects across different execution contexts.