In this specific situation I have a ModuleScript storing a bunch of information, however as ModuleScripts don’t replicate across all scripts requiring them it becomes kind of impractical when I for instance want to set a value in the ModuleScript outside it and have it replicate everywhere.
--modulescript
local module = {}
module.test = "Hello"
return module
Hmm, first ideal that comes to mind looking to avoid a datastore for this would be:
A folder with the values setup to be changed and read by the ModuleScript.
The kind you place in manually. # StringValue, BoolValue, # NumberValue.
Then you could read the .Value data or change it from the ModuleScript.
This is how others seem to do it. See this all the time.
ModuleScript values do not replicate to client/server. Each client/server gets their own copy, so if you change the value “test” on the server, it will not change on the client, you must use a remote event to detect the change.
That is not at all what the issue is. I want the changes to replicate on all server scripts, my issue doesn’t involve crossing the client-server boundary.
They work fine … Take a look at some of the more complicated free models. You will see folders like this in many of them under many names used for many things. They are like mini datastores with none of the cost. Roblox themselves do this all the time in their models.
Reading and writing values using instances is generally bad practice, unreliable, and slower. All of those I’d ideally like to avoid seeing as my use-case is a cryptographic module.
Sometimes works by using the __newindex metamethod like so. It doesn’t work all the time and is a bit wonky, hence I’m not marking it as a solution in case someone has a reliable way to fix the issue:
metatable.__newindex = function(table, key, value)
rawset(table,key,value)
end
I’m pretty sure that changes made in a module do replicate across all scripts requiring them on the same side of the client-server boundary. It looks like your method at the top was setting it from the script requiring the module. It should replicate, as long as the value is changed from within the module.
local module = {}
module.__index = module
module.someValue = nil
function module:ChangeValue(newValue)
self.someValue = newValue
end
return module
This has worked for me in the past. Hope it helps.
ModuleScripts should only run once per Luau VM and its return value should be cached. The only reason why your code example shouldn’t work properly (as in script 2 being able to read module.test2) is when the two scripts are in different Actors.
(Or if script 2 runs before script 1 and so prints nil because script 1 hasn’t run yet, but I assume that’s only an issue with this tiny repro you’ve provided)
What’s an Actor? I repro’d the example using the same set-up (Modulescript > Script, Script) except in ServerScriptService. It gave me the same output as in the screenshots, so didn’t work in Studio or the client.
I also ideally want the changes to sync no matter the loading time, so if I change/set a variable (in one Script’s environment) in the ModuleScript, I want it to sync to all other Scripts that have require’d the module, as well as any scripts that require the module in the future
--!strict
local Towers = {}
Towers.__index = Towers
function Towers.new()
-- loader function
local self = setmetatable({}, Towers)
self:init()
return self
function Towers:init()
-- init function
end
return Towers
, where I was requiring it with the .new() function. I re-tried just requiring it by itself without calling that function, where it worked, but the issue is I want to modify some variables which are first pre-loaded with .new(), which the synced modifying doesn’t work with (as it returns self). How would I go about doing that?
Here’s an example of what I want to do:
--!strict
local Towers = {}
Towers.__index = Towers
function Towers.new()
-- loader function
local self = setmetatable({}, Towers)
self:init()
return self
function Towers:init()
Towers.test = "Hello"
end
return Towers
--script
local Towers = require(script.Parent)
print(Towers) -- {}, as the __index returns the unmodified self table
print(Towers.test) -- "Hello", works, but only if I query it directly
I want the above snippet to somehow get the table environment containing the variable, but obviously calling it directly by .new() and getting it from there won’t sync the changes, nor will it show me the variable if I print the table due to the __index metamethod.