How can I make a value in a module not replicate?

Im not sure if you understand what I am going for here, I’m not replicating between clients, but replicating between instances of the server requiring a module, this has nothing to do with the client.

Thanks for your reply though!

oh i see now. Well logically the way i mentioned would be workable for module to module, but if u can provide some more info i.e the use case or behavior example of ur current code, it would be easier to identify

I dont think I really need to show code but uh, heres an example ig.

local Id = 0
local ThisId = 0
local module = {}

Id += 1
ThisId = Id

return module

Every time you require the module on the server, Id goes up by one.
I then want ThisId to be well Id, but if another script requires the module, ThisId will be set to the new Id value.

There are a few things you need to know about modules.

  1. They run once and only once when required the first time. Having multiple requires will not re-run the code in your module. The requires subsequent to the first one will have a reference to what was returned the first time around.

  2. You can not access local variables between module scripts unless you have a function returning their value.

Im aware, the module itself uses the local variable, not the scripts.

The behavior you want, which is for the ID to go up on each require, is not possible with the behavior of modules. What is your actual use case for something like this? I’m curious to know what made you approach things this way.

So the main point of this was for debugging purposes, as then I could tell what script changed what values with the help of metatables (specifically __newindex), in order to tell which script changed it I would just take the ThisId value, which well I explained above on how that works so yeah

There’s no way to detect a require call. However, as long as the instances that require the module have unique full names, you can use debug.info to identify the Script/LocalScript/ModuleScript that triggered the __newindex call.

Here’s an example of how this can be done. These example scripts (ModuleScripts and one Script) are in the same folder.

A ModuleScript called “ModuleWithRequireCounter”

local ModuleWithRequireCounter = {}

local COUNTER_VALUE_INDEX: string = "counter"

local counter: number = 0
local counterValuesForScriptInstanceFullNames: {[string]: number} = {}

-- This will return nil if there isn't an instance with this full name
-- or if there are multiple instances with this full name
-- (well, at least it should, I haven't tested it much).
local function getInstanceFromUniqueFullName(fullName: string): Instance?
	local currentParents: {Instance} = {game}
	for iName: number, name: string in string.split(fullName, ".") do
		local currentValidChildren: {Instance} = {}
		for _, parent: Instance in currentParents do
			for _, child: Instance in parent:GetChildren() do
				if child.Name ~= name then
					continue
				end
				table.insert(currentValidChildren, child)
			end
		end
		if #currentValidChildren == 0 then
			print(`Zero instances with full name {fullName}.`)
			return nil
		end
		currentParents = currentValidChildren
	end
	if #currentParents > 1 then
		print(`More than 1 instance with full name {fullName}`)
		return nil
	end
	return currentParents[1]
end

local function getId(): number
	local requiringInstanceFullName: string = debug.info(3, "s")
	if getInstanceFromUniqueFullName(requiringInstanceFullName) == nil then
		error(`There is not exactly one instance with this full name ({requiringInstanceFullName}).`
			.. "In order for the counter to be instance-spesific, the requiring instance"
			.. " must be the only instance with its full name.")
	end
	if counterValuesForScriptInstanceFullNames[requiringInstanceFullName] == nil then
		counter += 1
		counterValuesForScriptInstanceFullNames[requiringInstanceFullName] = counter
	end
	local id: number = counterValuesForScriptInstanceFullNames[requiringInstanceFullName]
	return id
end

local moduleData: {[any]: any} = {}

local metatable = {
	__newindex = function(_, index: any, value: any)
		local id: number = getId()
		print(`Code in instance with id {id} changed ModuleWithRequireCounter.{index} from {moduleData[index]} to {value}`)
		moduleData[index] = value
	end,
}
setmetatable(ModuleWithRequireCounter, metatable)

return ModuleWithRequireCounter

A ModuleScript called “RequireCounterTestModule1”

local requireCounterTestFolder = script.Parent

local ModuleWithRequireCounter = require(requireCounterTestFolder.ModuleWithRequireCounter)

local RequireCounterTestModule1 = {}

ModuleWithRequireCounter.value1 = 7

return RequireCounterTestModule1

A ModuleScript called “RequireCounterTestModule2”

local requireCounterTestFolder = script.Parent

local ModuleWithRequireCounter = require(requireCounterTestFolder.ModuleWithRequireCounter)

local RequireCounterTestModule2 = {}

ModuleWithRequireCounter.value2 = 9
ModuleWithRequireCounter.value1 = -3

return RequireCounterTestModule2

A ModuleScript called “RequireCounterTestModule3”

local requireCounterTestFolder = script.Parent

local ModuleWithRequireCounter = require(requireCounterTestFolder.ModuleWithRequireCounter)

local RequireCounterTestModule3 = {}

ModuleWithRequireCounter.value2 = 4
ModuleWithRequireCounter.value1 = -1
ModuleWithRequireCounter.value3 = -6

return RequireCounterTestModule3

A script

local requireCounterTestFolder = script.Parent

local RequireCounterTestModule1 = require(requireCounterTestFolder.RequireCounterTestModule1)
local RequireCounterTestModule2 = require(requireCounterTestFolder.RequireCounterTestModule2)
local RequireCounterTestModule3 = require(requireCounterTestFolder.RequireCounterTestModule3)
I initially understood your goal differently so here's what I first wrote but based on your latest reply, it doesn't actually seem to be exactly what you want.

Is it sufficient to have indexing the returned table with a specific key result in a different value depending on which Script/LocalScript/ModuleScript required the module? This can be achieved as long as the instances that require the module have unique full names.

Here’s an example of how this can be done.

A module script called “ModuleWithRequireCounter”

local ModuleWithRequireCounter = {}

local COUNTER_VALUE_INDEX: string = "counter"

local counter: number = 0
local counterValuesForScriptInstanceFullNames: {[string]: number} = {}

-- This will return nil if there isn't an instance with this full name
-- or if there are multiple instances with this full name
-- (well, at least it should, I haven't tested it much).
local function getInstanceFromUniqueFullName(fullName: string): Instance?
	local currentParents: {Instance} = {game}
	for iName: number, name: string in string.split(fullName, ".") do
		local currentValidChildren: {Instance} = {}
		for _, parent: Instance in currentParents do
			for _, child: Instance in parent:GetChildren() do
				if child.Name ~= name then
					continue
				end
				table.insert(currentValidChildren, child)
			end
		end
		if #currentValidChildren == 0 then
			print(`Zero instances with full name {fullName}.`)
			return nil
		end
		currentParents = currentValidChildren
	end
	if #currentParents > 1 then
		print(`More than 1 instance with full name {fullName}`)
		return nil
	end
	return currentParents[1]
end

local metatable = {
	__index = function(_, index: any)
		if index == COUNTER_VALUE_INDEX then
			local requiringInstanceFullName: string = debug.info(2, "s")
			if getInstanceFromUniqueFullName(requiringInstanceFullName) == nil then
				error(`There is not exactly one instance with this full name ({requiringInstanceFullName}).`
					.. "In order for the counter to be instance-spesific, the requiring instance"
					.. " must be the only instance with its full name.")
			end
			if counterValuesForScriptInstanceFullNames[requiringInstanceFullName] == nil then
				counter += 1
				counterValuesForScriptInstanceFullNames[requiringInstanceFullName] = counter
			end
			return counterValuesForScriptInstanceFullNames[requiringInstanceFullName]
		end
		return nil
	end,
}
setmetatable(ModuleWithRequireCounter, metatable)

return ModuleWithRequireCounter

A module script called “RequireCounterTestModule1”

local requireCounterTestFolder = script.Parent

local ModuleWithRequireCounter = require(requireCounterTestFolder.ModuleWithRequireCounter)

local RequireCounterTestModule1 = {}

task.spawn(function()
	print(`Counter value for test module 1: {ModuleWithRequireCounter.counter}`)
	task.wait(2)
	print(`Counter value for test module 1: {ModuleWithRequireCounter.counter}`)
end)

return RequireCounterTestModule1

A modulescript called “RequireCounterTestModule2”

local requireCounterTestFolder = script.Parent

local ModuleWithRequireCounter = require(requireCounterTestFolder.ModuleWithRequireCounter)

local RequireCounterTestModule2 = {}

task.spawn(function()
	print(`Counter value for test module 2: {ModuleWithRequireCounter.counter}`)
	task.wait(1)
	print(`Counter value for test module 2: {ModuleWithRequireCounter.counter}`)
end)

return RequireCounterTestModule2

A modulescript called “RequireCounterTestModule3”

local requireCounterTestFolder = script.Parent

local ModuleWithRequireCounter = require(requireCounterTestFolder.ModuleWithRequireCounter)

local RequireCounterTestModule3 = {}

task.spawn(function()
	print(`Counter value for test module 3: {ModuleWithRequireCounter.counter}`)
	task.wait(3)
	print(`Counter value for test module 3: {ModuleWithRequireCounter.counter}`)
end)

return RequireCounterTestModule3

A script

local requireCounterTestFolder = script.Parent

local RequireCounterTestModule1 = require(requireCounterTestFolder.RequireCounterTestModule1)
local RequireCounterTestModule2 = require(requireCounterTestFolder.RequireCounterTestModule2)
local RequireCounterTestModule3 = require(requireCounterTestFolder.RequireCounterTestModule3)
1 Like

sorry for the slight necro but I specifically mean instantiating a variable on only the server or client. if you’re doing that then I would move it to a module designed specifically for one or the other