How would I make it so 2 scripts can use a single module with the same values?

Let’s say I have 2 scripts, a client script and a tool script. Both of these reference the character module script and the character module script updates the isAlive value that is either true or false. The tool needs to use this value incase it gets equipped when the player is dead and automatically cease it’s function before the player can trigger anything and the client needs it to see for some GUI stuff.

How would I make it so both of these scripts get the same value from the same module?

1 Like

Use metatable.
whyis30charsathing

2 Likes

If I remember correctly, it’s quite simple. When you first require() a module, it runs the code and returns the table like you would expect. However, every other instance in which you require() that module it returns the same table. This means that if you make a change to the table in one place, every other place is looking at that same table and will be able to view the change.

The only time this breaks down is between client and server. If you require() the module on a local script and on a server script, they will both have their own instances of the module. As long as client script and tool script are both local scripts (or server), all you have to do is change the isAlive value and compare.

The technical term for what you’re trying to achieve is called a singleton. In programming, a singleton is a class or program which only has one instance of itself and can be referenced by many different scripts.

4 Likes

Does this mean it does it automatically without having to use metatables?

Ya, you shouldn’t need metatables. Try it out and see if it works

1 Like

Yep, I thought this required a metatable so I wanted to check if that’s the case or not. Thank you.

EDIT: Also thank you for the comprehensive explanation, always like to know all the ins and outs of things like these if I’m to use it.

1 Like

Great explanation. How would I do the opposite?
Suppose I want to create 2 balloons, each with their own “popped” property.

If I have a Balloon module with a function newBalloon() that returns a balloon Part, and the module also stores a module.popped property, is it possible to create an isolated scope for each balloon Part I create, so that if one balloon’s “popped” property is set to true, the other balloon’s “popped” property will not be changed?

Thanks.

There are probably a couple of different ways to do this, but the most common is through an Object-Oriented approach. There’s a couple of tutorials on the forum that explain it better, but basically you’ll set up a Balloon module that defines how all the functions about how a balloon behaves. Then define a constructor function that creates new balloons when called. By using metatables the new balloons are able to have all the same functions but still be identifiable from each other.

ex.

local Balloon = {}
Balloon.__index = Balloon

function Balloon:Pop()
    self.popped = true
    self.balloonPart:Destroy()
end

function Balloon.newBalloon() -- call Balloon.newBalloon() to make a new balloon
    local newBalloon = {}
    newBalloon.popped = false
    newBalloon.balloonPart = Instance.new("Part")
    setmetatable(newBalloon, Balloon)
    
    return newBalloon
end

return Balloon

Look through the devforum for some tutorials on OOP, because those will be able to explain it in a much more thorough manner.

1 Like

I know this is so old, however, I am running into an issue and this seems to be the closes solution that I have found.

Let’s say I have 2 local scripts, both client-side. I have 1 module script that creates a new “object” (using OOP) with a .new function. Now, let’s say I wanted to call object:DoSomething() on the first script, and object:DoSomethingElse() on the second script. They would both be methods of the same object, but they are called in different scripts.

How would I pass the object from the first script to the second script to be able to call methods on it?

I believe you could use events to pass this argument or use another modulescript where the object is created and have those interact with the object.

I’ve had another method I was using for a grid building script but for the love of me I can’t find it, will let you know if I do.

1 Like

So do you want a singular object returned by a module to 2 scripts?

It would be this code here but instead of returning Balloon you return Balloon.new()

1 Like

I know this might be late, however here’s a code snippet from my Character class that I have been using if you’re still looking for a solution:

local Character = {}
Character.__index = Character

local Cache = {}

function Character:Get(Player : Player)
	if Cache[Player.UserId] then
		return Cache[Player.UserId]
	end
end

function Character.New(Player : Player)
	local self = {}
	
	self.Player = Player
	
	setmetatable(self, Character)
	
	Cache[Player.UserId] = self
	
	return self
end

Essentially this also stores the Class in a cache if any external script needs to fetch a character, right now I haven’t actually tested if it works since I don’t have any scripts that are using this function however I’ve implemented similar method in my networking system and it seems to work as intended.

1 Like