Is it possible to tell when someone gets a variable?

So I have worked with engines in the past, and some of them (godot) contain the feature to tell when someone gets a value, you can then trigger a function and decide what to return, ex:

var MyValue = 50 :
    get() : 
        return 1 # this can be replaced with whatever I would want to return.

now thats what it is in godot, but does roblox have a similar feature? Im currently working on a system that would be very nice if I could have this lol

1 Like

You can only achieve that with metatables. Use __index metamethod.

1 Like

: O
THIS IS A THING!!

Ok I can totally try using this! I was planning to use metatables anyways so this should work just fine!
Thanks!

1 Like

Wait how can I actually do this? I’ve been trying to figure it out, but honestly metatables confuse me, so heres my code if you need it:

-- // Services //
local players = game:GetService('Players')
local runService = game:GetService('RunService')

-- // Values //
local module = {}

-- // Main Code //
if getmetatable(module) then
	return getmetatable(module)
else
	local self = {}
	self.__index = {x = 1}
	
	setmetatable(module,self)
	return getmetatable(module)
end

when I get the metatable and try to get the x value it gives me nil, as it seems well it doesnt exist lol

This isn’t necessary, when you set the metatable, just return the original table. What you’re doing here is returning the metatable assigned to the original table.

-- // Services //
local players = game:GetService('Players')
local runService = game:GetService('RunService')

-- // Values //
local module = {}

-- // Main Code //
if getmetatable(module) then 
    -- i'm also confused about this;
    -- if this is a ModuleScript, this check will always fail because
    -- modulescripts are cached the first time they are required.
    -- essentially, once this ModuleScript runs the first time, the metatable
    -- will *always* be assigned.
    -- you don't have to include this check here; the 'else' condition will work fine on its own
	return module
else
	local self = {}
	self.__index = {x = 1}
	
	setmetatable(module,self)
	return module
end

Some other script:

local module = require(path.to.module)
print(module.x) --> prints 1

Waiittt this whole time I’ve been returning self, and now that I’m returning module it works. Tysm!

Hmm so I was told that if I update a metatable via the server it’ll update on the client, but it seems only if I pass that metatable to the client probably, so any way to deal with that? Cause when the client or some other scripts accesses this module I would like to return the metatable as you can probably figure from my code

Metatables can’t pass through the client/server boundary; when you require a ModuleScript on the client and on the server, they receive two different versions of the ModuleScript for their respective context.

Once one script uses require on the modulescript, every following script (with the same context) will receive the same returned value since it’s cached:

-- ModuleScript
local module = { k = 2 }
return module

-- Script 1
local value = ModuleScript.k
print(value) --> prints 2

-- Script 2
ModuleScript.k += 1
print(ModuleScript.k) -- prints 3

-- Script 3
print(ModuleScript.k) -- this also prints '3' because each script accesses the same value returned from the module script

ModuleScripts don’t run more than once; they will just return their cached value after the first require

1 Like

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