Plugin global doesn't exist in module script under plugin script?

Error: attempt to index nil with 'GetSetting'

Code:

local key = "data"

local function load()
    return plugin:GetSetting(key)
end

This code is inside a module script that will utilize the function after the script calls it in which load is utilized. Printing plugin ~= nil inside the module gives false so it’s definitely being seen as nil.

The script just doesn’t continue due to the error after requiring the module so the script’s code is really not that useful here; local module = require(script.Module)

However, the original plugin script doesn’t see plugin as nil (I tested with a print before requiring the module), why is the module despite it should be sharing context, not able to see plugin to exist?

1 Like

I’m guessing Roblox only included the plugin global for Script instances and not modules, since certain ModuleScript setups are designed to only offer features to the central script and not require access to data that isn’t easily accessible.

You can use a workaround that some plugins do, which is passing plugin to a initialization function of the ModuleScript so it can be used outside of standard Scripts. Example:

-- Main Script
local Module = require(script.Module);
Module.init(plugin); -- sends the Plugin instance as an argument
-- load stuff here
Module.execute(data);
-- Module Script
local Module = {};
local plugin; -- defined here so it's available everywhere in this ModuleScript
function Module.init(pluginReference)
	assert(type(pluginReference) == "Instance" and pluginReference:IsA("Plugin"));
	plugin = pluginReference;
end;
function Module.execute(data)
	-- perform stuff that requires the Plugin instance
end;
2 Likes

Also note it is possible to store the plugin instance within an ObjectValue which avoids the need to any form on init function.

One solution is to put an ObjectValue at the top level of your plugin and access this each time (this can get messy).

Another solution would be to put a ObjectValue contining the plugin value as a child of all module scripts within the plugin.

Main script

do
	-- share plugin with module scripts within the plugin folder
	for _, ins in pairs(script.Parent:GetDescendants()) do
		if ins:IsA('ModuleScript') then
			local objVal = Instance.new('ObjectValue')
			objVal.Name = 'PluginObj'
			objVal.Value = plugin
			objVal.Parent = ins
		end
	end
end

Module Script

local plugin = script.PluginObj.Value
...
1 Like