New to Object Oriented Programming - How get object from other script?

I am new to Object Oriented Programming and I am just trying to experiment. I made a car but I want to be able to access the same car and its properties from another script and I am not sure how to do that or if it’s even possible.

I have this in a module script:

local Car = {}
Car.__index = Car

function Car.new(owner, color) -- Constructor
	local newCar = {}
	setmetatable(newCar,Car)
	
	newCar.Owner = owner -- Owner property
	newCar.Color = color -- Color property
	
	return newCar
end

return Car

If I made a new car in a server script:

local Car = require(game:GetService("ReplicatedStorage").Car)
local newCar = Car.new(plr,"red") -- Making the car

Is it possible for me to access the same car on a different server script? This question came up when I wanted to paint an already existing car with a function like car:Paint() from a different script than the one I made the car with.

2 Likes

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.

11 Likes

Thank you for helping, Nachiyen! That was really well explained and easy to follow, even in the eyes of someone who has not done OOP before.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.