How to detect value in ModuleScript was changed from LocalScript?

I’m creating a Settings menu for my game and all of the settings are stored within a ModuleScript. The settings can change and work, but scripts outside of the modulescript that are supposed to recognize scripts within the ModuleScript have changed do not recognize that there is a change. What could be the cause of this? I’ve searched through the DevForums, but have yet to find a good answer.

Code that is supposed to recognize a value was changed in the ModuleScript:

SettingsModule.Value.Changed:Connect(ToggleFPS)

Help appreciated, thank you!

3 Likes

If the Value is called Value then do the following:

SettingsModule.Value:GetPropertyChangedSignal("Value"):Connect(ToggleFPS)
1 Like

Heads up, continuing the thought on this script fragment, :GetPropertyChangedSignal() does NOT pass the value that changed.

1 Like

Facts, he will have to check again the value doing something like this:

function ToggleFPS()
    print(SettingsModule.Value.Value)
end

SettingsModule.Value:GetPropertyChangedSignal("Value"):Connect(ToggleFPS)
1 Like

To clarify, SettingsModule is the result of the require() function, and the settings are being stored as values inside of a table in that ModuleScript rather than as instances parented to it?

If so, one way to fix this is to have a main table and a “proxy” table in the modulescript. The proxy table will hold all the contents, while the main table will start off empty so that the metamethods __newindex and __index can fire.

Modulescript:

local main = {}
local proxy = {}

-- set all your values here:
proxy.foo = "bar"

-- connect the Changed event:
-- the event will not fire for any variables declared above this line
local event = Instance.new("BindableEvent")
proxy.Changed = event.Event

-- set metatables:
return setmetatable(main, {
    __index = proxy,
    __newindex = function(t, i, v)
        if t[i] ~= v then
            proxy[i] = v
            event:Fire(i, v)
        end
    end
})

Script:

local SettingsModule = require()--location of the module

SettingsModule.Changed:Connect(function(PropertyName, NewValue)
    print(tostring(PropertyName) .. " has changed to " .. tostring(NewValue))
end)

SettingsModule.ExampleValue = true
-- ExampleValue has changed to true

SettingsModule.ExampleValue = false
-- ExampleValue has changed to false

Not sure if this is the cleanest or most efficient solution, but it has worked for me in the past.

2 Likes

You could use a signal class. Theres a ton of them in community resources

1 Like

The value’s name is “FPS.” I implemented this code and it’s still not working. I changed SettingsModule.Value to SettingsModule.FPS and changed (“Value”) to FPS and left (“Value”) as is but neither recognized a change.

The values in my ModuleScript aren’t bool values.

It looks like this:

local Settings = {
	FPS = false,
	Static = true,
	AspectRatio = true,
}

I tried this and it still doesn’t register as changed. Also, yes the settings are being stored as values inside of a table and SettingsModule is a require() leading to the module.

main {} in your script looks like the script below in my script.

local Settings = {
	FPS = false,
	Static = true,
	AspectRatio = true,
}

main is supposed to start off empty. You need to add the default values to the`proxy table.

local main = {}
local proxy = {}

-- set all your values here:
proxy.FPS = false
proxy.Static = true
proxy.AspectRatio = true

...

Instead of setting the values by doing proxy.x = y, could I do the code below?

local Settings = {
	FPS = false,
	Static = true,
	AspectRatio = true,
}

I don’t see why that shouldn’t work, as long as you declare and initialize it before you connect the Changed event

Of course, if you want the variable to be named anything other than “proxy” you will have to replace the other occurences of the word “proxy” in the script I wrote.

Ok, thanks. It all works now. :+1:

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